home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / oldwish / wishScroll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-07-13  |  7.4 KB  |  254 lines

  1. /* 
  2.  * WishScroll.c --
  3.  *
  4.  *    Routines for dealing with scrolling.
  5.  *
  6.  * Copyright 1987 Regents of the University of California
  7.  * All rights reserved.
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /a/newcmds/wish/RCS/wishScroll.c,v 1.3 89/01/11 11:58:35 mlgray Exp Locker: mgbaker $ SPRITE (Berkeley)";
  19. #endif not lint
  20.  
  21.  
  22. #include "string.h"
  23. #include "sx.h"
  24. #include "wishInt.h"
  25.  
  26. /* This is global for now but will go into WishWindow structure... */
  27. extern    int    wishNumGroupsToHide;
  28. extern    Boolean    wishSkipEmptyGroupsP;
  29.  
  30.  
  31. /*
  32.  *----------------------------------------------------------------------
  33.  *
  34.  * WishScroll --
  35.  *
  36.  *    Scrollbar call-back routine.
  37.  *
  38.  * Results:
  39.  *    None.
  40.  *
  41.  * Side effects:
  42.  *    The display may scroll.
  43.  *
  44.  *----------------------------------------------------------------------
  45.  */
  46. void
  47. WishScroll(clientData, distance, units, window)
  48.     ClientData    clientData;
  49.     float    distance;
  50.     int        units;    /*  SX_SCROLL_ABSOLUTE or ..._PAGES */
  51.     Window    window;
  52. {
  53.     float    top, bottom;
  54.     float    newTop, newBottom;
  55.     WishWindow    *aWindow;
  56.     float    displayCover;        
  57.     int        oldFirstElement;
  58.     int        newLastElement;
  59.     int        numDisplayed;
  60.     int        numCouldDisplay;
  61.  
  62.     aWindow = (WishWindow *) clientData;
  63.  
  64. #ifdef SCROLL_DEBUG
  65.     fprintf(stderr, "Entered WishScroll:\n");
  66.     fprintf(stderr, "\tdistance is %f\n", distance);
  67.     fprintf(stderr, "\tunits is %s\n", units == SX_SCROLL_PAGES ?
  68.         "scroll_pages" : "scroll_absolute");
  69.     fprintf(stderr, "\tfirstElement is %d\n",
  70.         aWindow->firstElement);
  71.     fprintf(stderr, "\tlastElement is %d\n",
  72.         aWindow->lastElement);
  73.     fprintf(stderr, "\tnumElements is %d\n",
  74.         aWindow->numElements);
  75.     fprintf(stderr, "\tnumGroups is %d\n",
  76.         aWindow->numGroups);
  77. #endif SCROLL_DEBUG
  78.  
  79.     oldFirstElement = aWindow->firstElement;    /* save to compare */
  80.     numCouldDisplay = aWindow->numRows * (aWindow->usedCol + 1);
  81.     numDisplayed = aWindow->lastElement - aWindow->firstElement + 1;
  82.  
  83.     if (units == SX_SCROLL_PAGES) {
  84.     /*
  85.      * If we're supposed to scroll forwards, check to see if the end of
  86.      * the display has already been reached.
  87.      */
  88.     if (distance > 0 && (numDisplayed < numCouldDisplay ||
  89.         aWindow->lastElement >= aWindow->totalDisplayEntries)) {
  90.         return;    /* No point -- already hit end of display */
  91.     }
  92.     aWindow->firstElement += distance * numCouldDisplay;
  93.     /* no point in scrolling so that we waste space in last column */
  94.     if (aWindow->firstElement + numCouldDisplay - 1 >
  95.         aWindow->totalDisplayEntries) {
  96.         aWindow->firstElement = aWindow->totalDisplayEntries -
  97.             numCouldDisplay + 1;
  98.     }
  99.     /* The lowest numbered element that makes sense is number 1 */
  100.     if (aWindow->firstElement < 1) {
  101.         aWindow->firstElement = 1;
  102.     }
  103.     if (aWindow->firstElement == oldFirstElement) {
  104.         return;    /* no change */
  105.     }
  106.     newLastElement = aWindow->firstElement + numCouldDisplay - 1;
  107.  
  108. #ifdef SCROLL_DEBUG
  109.     fprintf(stderr,
  110.         "WishScroll dealing with page scrolling:\n");
  111.     fprintf(stderr, "\tfirstElement is %d\n",
  112.         aWindow->firstElement);
  113.     fprintf(stderr, "\tnewLastElement is %d\n",
  114.         newLastElement);
  115.     fprintf(stderr, "\tcalling SetPositions and Redraw\n");
  116. #endif SCROLL_DEBUG
  117.  
  118.     /* scroll */
  119.     WishSetPositions(aWindow);
  120.     /*
  121.      * WishRedraw will be called from event caused in
  122.      * WishSetPositions().
  123.      */
  124.  
  125. #ifdef SCROLL_DEBUG
  126.     {
  127.         float    a, b;
  128.  
  129.         fprintf(stderr,
  130.             "End of WishScroll dealing with page scrolling:\n");
  131.         fprintf(stderr, "\tfirstElement is %d\n",
  132.             aWindow->firstElement);
  133.         fprintf(stderr, "\tlastElement is %d\n",
  134.             aWindow->lastElement);
  135.         Sx_ScrollbarGetRange(wishDisplay, window, &a, &b);
  136.         fprintf(stderr, "\ttop is now %f\n", a);
  137.         fprintf(stderr, "\tbottom is now %f\n", b);
  138.     }
  139. #endif SCROLL_DEBUG
  140.  
  141.     return;
  142.     }
  143.     if (units != SX_SCROLL_ABSOLUTE) {
  144.     Sx_Panic(wishDisplay,
  145.         "In WishScroll(): Unknown scrolling method requested.");
  146.     }
  147.     /* SX_SCROLL_ABSOLUTE from here on */
  148.  
  149.     Sx_ScrollbarGetRange(wishDisplay, window, &top, &bottom);
  150.  
  151. #ifdef SCROLL_DEBUG
  152.     fprintf(stderr, "\tbefore scrolling, top is %f\n", top);
  153.     fprintf(stderr, "\tbefore scrolling, bottom is %f\n", bottom);
  154. #endif SCROLL_DEBUG
  155.  
  156.     if (aWindow->numElements <= 0) {
  157.     displayCover = 1.0;
  158.     } else {
  159.     /* The portion of the total entries that can be visible. */
  160.     displayCover = ((float) numCouldDisplay) /
  161.         ((float) aWindow->totalDisplayEntries);
  162.     if (displayCover > 1.0) {
  163.         displayCover = 1.0;     /* can't cover more than all of it */
  164.     }
  165.     }
  166. #ifdef SCROLL_DEBUG
  167.     fprintf(stderr, "\tdisplayCover is %f\n", displayCover);
  168. #endif SCROLL_DEBUG
  169.  
  170.     newTop = distance - (displayCover / 2.0);
  171.     newBottom = distance + (displayCover / 2.0);
  172.     if (newTop < 0) {
  173.     newTop = 0.0;
  174.     newBottom = displayCover;
  175.     }
  176.     if (newBottom > 1.0) {
  177.     newBottom = 1.0;
  178.     newTop = 1.0 - displayCover;
  179.     }
  180.     if (newTop == top && newBottom == bottom) {
  181.     return;        /* no change */
  182.     }
  183.     /*
  184.      * I set firstElement from newTop unless newBottom happens to be
  185.      * the very end.  If so, I make sure that the last element should
  186.      * be visible to avoid roundoff errors.
  187.      */
  188.     if (newBottom == 1.0) {
  189.     newLastElement = aWindow->totalDisplayEntries;
  190.     aWindow->firstElement = aWindow->totalDisplayEntries -
  191.         numCouldDisplay + 1;
  192.     /*
  193.      * If there are fewer things to display than there are spaces,
  194.      * the above would leave firstElement < 0.  The lowest element
  195.      * we can start displaying is the first element.  (firstElement
  196.      * is incremented below by one.)
  197.      */
  198.     if (aWindow->firstElement < 1) {
  199.         aWindow->firstElement = 1;
  200.     }
  201.     } else {
  202.     aWindow->firstElement =
  203.         (int) (newTop * aWindow->totalDisplayEntries) + 1;
  204. #ifdef NOTDEF
  205.     /* this seems not to be necessary */
  206.     newLastElement = aWindow->firstElement + numCouldDisplay - 1;
  207. #endif NOTDEF
  208.     }
  209. #ifdef SCROLL_DEBUG
  210.     fprintf(stderr, "In WishScroll, after calculations:\n");
  211.     fprintf(stderr, "\tfirstElement is %d\n",
  212.         aWindow->firstElement);
  213.     fprintf(stderr, "\tnewLastElement is %d\n",
  214.         newLastElement);
  215.     fprintf(stderr, "\tnewTop is %f\n", newTop);
  216.     fprintf(stderr, "\tnewBottom is %f\n", newBottom);
  217.     fprintf(stderr,
  218.         "\tcalling WishSetPositions, then WishRedraw\n");
  219. #endif SCROLL_DEBUG
  220.     if (oldFirstElement == aWindow->firstElement) {
  221.     return;        /* no change */
  222.     }
  223.  
  224.     WishSetPositions(aWindow);
  225.  
  226.     /* Things are where we want them.  WishRedraw() should be called
  227.      * as a result of an event caused in WishSetPositions.  WishRedraw()
  228.      * will call SetRange again...  Go scroll.
  229.      */
  230.     
  231. #ifdef SCROLL_DEBUG
  232.     {
  233.     float    a, b;
  234.  
  235.     Sx_ScrollbarGetRange(wishDisplay, window, &a, &b);
  236.     fprintf(stderr, "At end of WishScroll:\n");
  237.     fprintf(stderr, "\tnewTop was supposed to be %f\n", newTop);
  238.     fprintf(stderr, "\tnewBottom was supposed to be %f\n",
  239.         newBottom);
  240.     fprintf(stderr, "\tRedraw called SetRange and:\n");
  241.     fprintf(stderr, "\ttop is really %f\n", a);
  242.     fprintf(stderr, "\tbottom is really %f\n", b);
  243.     fprintf(stderr, "\tfirstElement is %d\n",
  244.         aWindow->firstElement);
  245.     fprintf(stderr, "\tlastElement is %d\n",
  246.         aWindow->lastElement);
  247.     fprintf(stderr, "\tnumElements is %d\n",
  248.         aWindow->numElements);
  249.     }
  250. #endif SCROLL_DEBUG
  251.  
  252.     return;
  253. }
  254.